@@ -1,4 +1,6 @@ |
||
1 | 1 |
class AgentsController < ApplicationController |
2 |
+ include DotHelper |
|
3 |
+ |
|
2 | 4 |
def index |
3 | 5 |
@agents = current_user.agents.page(params[:page]) |
4 | 6 |
|
@@ -14,19 +14,4 @@ module ApplicationHelper |
||
14 | 14 |
link_to '<span class="label label-warning">No</span>'.html_safe, agent_path(agent, :tab => (agent.recent_error_logs? ? 'logs' : 'details')) |
15 | 15 |
end |
16 | 16 |
end |
17 |
- |
|
18 |
- def render_dot(dot_format_string) |
|
19 |
- if (command = ENV['USE_GRAPHVIZ_DOT']) && |
|
20 |
- (svg = IO.popen([command, *%w[-Tsvg -q1 -o/dev/stdout /dev/stdin]], 'w+') { |dot| |
|
21 |
- dot.print dot_format_string |
|
22 |
- dot.close_write |
|
23 |
- dot.read |
|
24 |
- } rescue false) |
|
25 |
- svg.html_safe |
|
26 |
- else |
|
27 |
- tag('img', src: URI('https://chart.googleapis.com/chart').tap { |uri| |
|
28 |
- uri.query = URI.encode_www_form(cht: 'gv', chl: dot_format_string) |
|
29 |
- }) |
|
30 |
- end |
|
31 |
- end |
|
32 | 17 |
end |
@@ -0,0 +1,40 @@ |
||
1 |
+module DotHelper |
|
2 |
+ def render_agents_diagram(agents) |
|
3 |
+ if (command = ENV['USE_GRAPHVIZ_DOT']) && |
|
4 |
+ (svg = IO.popen([command, *%w[-Tsvg -q1 -o/dev/stdout /dev/stdin]], 'w+') { |dot| |
|
5 |
+ dot.print agents_dot(agents, true) |
|
6 |
+ dot.close_write |
|
7 |
+ dot.read |
|
8 |
+ } rescue false) |
|
9 |
+ svg.html_safe |
|
10 |
+ else |
|
11 |
+ tag('img', src: URI('https://chart.googleapis.com/chart').tap { |uri| |
|
12 |
+ uri.query = URI.encode_www_form(cht: 'gv', chl: agents_dot(agents)) |
|
13 |
+ }) |
|
14 |
+ end |
|
15 |
+ end |
|
16 |
+ |
|
17 |
+ private |
|
18 |
+ |
|
19 |
+ def dot_id(string) |
|
20 |
+ # Backslash escaping seems to work for the backslash itself, |
|
21 |
+ # despite the DOT language document. |
|
22 |
+ '"%s"' % string.gsub(/\\/, "\\\\\\\\").gsub(/"/, "\\\\\"") |
|
23 |
+ end |
|
24 |
+ |
|
25 |
+ def agents_dot(agents, rich = false) |
|
26 |
+ "digraph foo {".tap { |dot| |
|
27 |
+ agents.each.with_index do |agent, index| |
|
28 |
+ if rich |
|
29 |
+ dot << '%s[URL=%s];' % [dot_id(agent.name), dot_id(agent_path(agent.id))] |
|
30 |
+ else |
|
31 |
+ dot << '%s;' % dot_id(agent.name) |
|
32 |
+ end |
|
33 |
+ agent.receivers.each do |receiver| |
|
34 |
+ dot << "%s->%s;" % [dot_id(agent.name), dot_id(receiver.name)] |
|
35 |
+ end |
|
36 |
+ end |
|
37 |
+ dot << "}" |
|
38 |
+ } |
|
39 |
+ end |
|
40 |
+end |
@@ -9,17 +9,7 @@ |
||
9 | 9 |
</div> |
10 | 10 |
|
11 | 11 |
<div class='digraph'> |
12 |
- <% |
|
13 |
- dot_format_string = "digraph foo {" |
|
14 |
- @agents.each.with_index do |agent, index| |
|
15 |
- dot_format_string += "\"#{agent.name}\";" |
|
16 |
- agent.receivers.each do |receiver| |
|
17 |
- dot_format_string += "\"#{agent.name}\"->\"#{receiver.name}\";" |
|
18 |
- end |
|
19 |
- end |
|
20 |
- dot_format_string = dot_format_string + "}" |
|
21 |
- %> |
|
22 |
- <%= render_dot(dot_format_string) %> |
|
12 |
+ <%= render_agents_diagram(@agents) %> |
|
23 | 13 |
</div> |
24 | 14 |
</div> |
25 | 15 |
</div> |
@@ -0,0 +1,48 @@ |
||
1 |
+require 'spec_helper' |
|
2 |
+ |
|
3 |
+describe DotHelper do |
|
4 |
+ describe "#dot_id" do |
|
5 |
+ it "properly escapes double quotaion and backslash" do |
|
6 |
+ dot_id('hello\\"').should == '"hello\\\\\\""' |
|
7 |
+ end |
|
8 |
+ end |
|
9 |
+ |
|
10 |
+ describe "with example Agents" do |
|
11 |
+ class Agents::DotFoo < Agent |
|
12 |
+ default_schedule "2pm" |
|
13 |
+ |
|
14 |
+ def check |
|
15 |
+ create_event :payload => {} |
|
16 |
+ end |
|
17 |
+ end |
|
18 |
+ |
|
19 |
+ class Agents::DotBar < Agent |
|
20 |
+ cannot_be_scheduled! |
|
21 |
+ |
|
22 |
+ def check |
|
23 |
+ create_event :payload => {} |
|
24 |
+ end |
|
25 |
+ end |
|
26 |
+ |
|
27 |
+ before do |
|
28 |
+ stub(Agents::DotFoo).valid_type?("Agents::DotFoo") { true } |
|
29 |
+ stub(Agents::DotBar).valid_type?("Agents::DotBar") { true } |
|
30 |
+ end |
|
31 |
+ |
|
32 |
+ describe "#agents_dot" do |
|
33 |
+ it "generates a DOT script" do |
|
34 |
+ @foo = Agents::DotFoo.new(:name => "foo") |
|
35 |
+ @foo.user = users(:bob) |
|
36 |
+ @foo.save! |
|
37 |
+ |
|
38 |
+ @bar = Agents::DotBar.new(:name => "bar") |
|
39 |
+ @bar.user = users(:bob) |
|
40 |
+ @bar.sources << @foo |
|
41 |
+ @bar.save! |
|
42 |
+ |
|
43 |
+ agents_dot([@foo, @bar]).should == 'digraph foo {"foo";"foo"->"bar";"bar";}' |
|
44 |
+ agents_dot([@foo, @bar], true).should == 'digraph foo {"foo"[URL="/agents/%d"];"foo"->"bar";"bar"[URL="/agents/%d"];}' % [@foo.id, @bar.id] |
|
45 |
+ end |
|
46 |
+ end |
|
47 |
+ end |
|
48 |
+end |